package com.test.enc;

import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.test.enc.common.Constant;
import com.test.enc.util.DateUtil;
import com.test.enc.util.PropertiesUtil;
import com.test.enc.util.TarArchiveUtil;
import org.bouncycastle.util.encoders.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileFilter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Sm4EncryptFile {

    private static Logger logger = LoggerFactory.getLogger(Sm4EncryptFile.class);

    public static void main(String[] args) throws Exception {
        String path = args[0];
        boolean directory = Files.isDirectory(Paths.get(path));
        if (!directory) {
            logger.error("input params[0] is not a directory.");
            return;
        }
        File rootFile = new File(path);
        File[] files = rootFile.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return !Constant.COMPRESS_FILE_OUT_PATH.equals(file.getName());
            }
        });
        if (files == null || files.length == 0) {
            logger.error("input params[0] directory is empty.");
            return;
        }
        logger.info("start compress files.");
        for (File compressFile : files) {
            String compressFileName = compressFile.getName();
            if (!compressFile.isDirectory()) {
                logger.warn("[{}] is not a directory, skip compress.", compressFileName);
                continue;
            }
            doCompressFile(compressFile);
        }
        logger.info("end compress files.");
    }

    private static void doCompressFile(File compressFile) throws Exception {
        logger.info("compress file [{}]", compressFile.getName());
        String rootPath = compressFile.getParent();
        String compressFileName = compressFile.getName();
        String path = compressFile.getPath();
        String currentDateTime = DateUtil.getCurrentDateTime();
        String fileName = compressFileName + Constant.FILE_EXTENSION_GZ + Constant.DOT + currentDateTime;
        String okFileName = compressFileName + Constant.FILE_EXTENSION_OK + Constant.DOT + currentDateTime;
        String gzFilePath = rootPath + File.separator + fileName;
        TarArchiveUtil.compress(path, gzFilePath);
        String outPath = rootPath + File.separator + Constant.COMPRESS_FILE_OUT_PATH + File.separator;
        Files.createDirectories(Paths.get(outPath));
        String outFilePath = outPath + fileName;
        String okFilePath = outPath + okFileName;
        File outfile = new File(gzFilePath);
        byte[] SM4_KEY = Hex.decode(PropertiesUtil.get(Constant.PROPERTIES_SM4_KEY));
        // 对gz文件加密
        SymmetricCrypto sm4 = SmUtil.sm4(SM4_KEY);
        byte[] encryptByte = sm4.encrypt(Files.readAllBytes(Paths.get(outfile.getPath())));
        // 加密后字节写入文件
        Files.write(Paths.get(outFilePath), encryptByte);
        // 获取加密文件摘要
        String sm3 = SmUtil.sm3(new File(outFilePath));
        sm3 = fileName.concat(Constant.OK_FILE_CONTENT_SEPARATOR).concat(sm3);
        // sm3写入ok文件
        Files.write(Paths.get(okFilePath), sm3.getBytes(StandardCharsets.UTF_8));
        Files.deleteIfExists(Paths.get(gzFilePath));
    }
}
